<template>
  <div class="layoutContainer" :style="commpStyle">
    <!--        <el-row class="layoutRow" :key="'rowIndex_'+rowIndex" v-for="(rowIndex) in Number(layout.row)">-->
    <!--            <el-col class="layoutCol resizable" :key="rowIndex+'_colIndex_'+colIndex" v-for="(colIndex) in Number(layout.col)" :span="24/Number(layout.col)" :style="setComponentStyle(layout.render, rowIndex, colIndex)">-->
    <!--                <component :is="getSubComponent(layout.render, rowIndex, colIndex)" v-bind="getSubComponentParams(layout.render, rowIndex, colIndex)" v-on="getSubComponentEvent(layout.render, rowIndex, colIndex)" :multiple="false">-->
    <!--                    <span v-html="getSubComponentHtml(layout.render, rowIndex, colIndex)"></span>-->
    <!--                </component>-->
    <!--            </el-col>-->
    <!--        </el-row>-->
    <div class="resizableRow" :key="'rowIndex_'+rowIndex" v-for="(rowIndex) in Number(layout.row)">
      <!-- <div class="resizableRowContent"> -->
      <div class="resizableCol" :key="rowIndex+'_colIndex_'+colIndex" v-for="(colIndex) in Number(layout.col)"
           :style="renderStyle[rowIndex+'-'+colIndex]">
        <!-- <div class="resizableColContent"> -->
        <component v-if="getRenderType(rowIndex, colIndex) == 'commp'" :is="getSubComponent(rowIndex, colIndex)"
                   v-bind="getSubComponentParams(rowIndex, colIndex)" v-on="getSubComponentEvent(rowIndex, colIndex)"
                   :multiple="false">
          <span v-if="getSubComponentHtml(rowIndex, colIndex)" v-html="getSubComponentHtml(rowIndex, colIndex)"></span>
        </component>
        <CommonConfigForm v-else-if="getRenderType(rowIndex, colIndex) == 'design'"
                          :option="uiContents[rowIndex+'-'+colIndex]"
                          v-bind="defaultData[rowIndex+'-'+colIndex]"></CommonConfigForm>
      </div>
      <!-- </div> -->
    </div>
  </div>
</template>

<script>
//引入Jquery
import CommonConfigForm from "./commonConfigForm.vue";
import BaseComp from "./baseComp";

export default {
  name: "layoutContainer",
  extends: BaseComp,
  components: {CommonConfigForm},
  model: {
    prop: 'layoutValue',
    event: 'layoutChange'
  },
  props: {
    layout: {
      type: Object,
      default: () => {
        return {
          row: 0,
          col: 0,
          render: [
            // {rowNum: 1,colNum: 1,component: '',width: '',height: '', minWidth: '', minHeight: "", config: {}}
          ],
          renderStyle: []
        }
      }
    },
    layoutValue: [Object, String]
  },
  watch: {
    layout: {
      handler(val) {
        if(!val){
          return;
        }
        if(val.renderStyle){
          this.createLayoutStyle(val.renderStyle);
        }
        if(val.render){
          this.queryStrategyUi(val.render);
        }
      },
      immediate: true, //刷新加载 立马触发一次handler
      deep: true, // 可以深度检测到 obj 对象的属性值的变化
    },
    layoutValue: {
      handler(val) {
        if (val) {
          this.defaultData = val;
        }
      },
      immediate: true,  //刷新加载 立马触发一次handler
      deep: true  // 可以深度检测到 obj 对象的属性值的变化
    },
    defaultData: {
      handler(val) {
        if (val) {
          this.$emit('layoutChange', val);
        }
      },
      immediate: true,  //刷新加载 立马触发一次handler
      deep: true  // 可以深度检测到 obj 对象的属性值的变化
    }
  },
  data() {
    return {
      defaultData: {},
      uiContents: {}, //存储设计界面的JSON数据内容
      renderStyle: {}, //存储布局组件的样式数据内容
    }
  },
  mounted() {
    this.loadTheme(this.$options.name)
    //修改自身父类el-form-item的底边距
    let currentEl = this.$el;
    let elItem = jQuery(currentEl).closest('.el-form-item');
    elItem.css('margin-bottom', '0px');
  },
  created() {},
  methods: {
    /**
     *
     * @param {需要渲染的数据集} dataList
     * @param {行索引} rowIndex
     * @param {列索引} colIndex
     */
    getRenderType(rowIndex, colIndex) {
      //   let item = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      let item = this.uiContents[rowIndex + '-' + colIndex];
      if (!item) {
        return;
      }
      if (item.component.startsWith('url')) {
        return 'url';
      } else if (item.component.startsWith('design')) {
        return 'design';
      } else {
        return 'commp';
      }
    },
    /**
     *
     * @param {需要渲染的数据集} dataList
     * @param {行索引} rowIndex
     * @param {列索引} colIndex
     */
    getSubComponent(rowIndex, colIndex) {
      //   let component = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      let component = this.uiContents[rowIndex + '-' + colIndex];
      return this.getComponent(component);
    },
    /**
     * 获取组件渲染参数
     * @param rowIndex  this.toolbar.custom.render
     * @param colIndex
     * @returns {string|*}
     */
    getSubComponentParams(rowIndex, colIndex) {
      //   let component = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      let item = this.uiContents[rowIndex + '-' + colIndex];
      if (item.component.startsWith('design')) {
        return {};
      }
      let commpValue = this.defaultData[rowIndex + '-' + colIndex];
      let compParam = this.getComponentParams(item);
      if (commpValue) {
        compParam = {...compParam, ...commpValue};
      }
      return compParam;
    },
    /**
     * 获取组件事件
     */
    getSubComponentEvent(rowIndex, colIndex) {
      //   let component = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      let item = this.uiContents[rowIndex + '-' + colIndex];
      if (item.component.startsWith('design')) {
        return {};
      }
      return this.getComponentEvent(item);
    },
    /**
     * 获取组件html
     */
    getSubComponentHtml(rowIndex, colIndex) {
      //   let component = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      let component = this.uiContents[rowIndex + '-' + colIndex];
      return this.getComponentHtml(component);

      let data = []

    },
    /**
     * 设置组件样式，在组件样式配置基础上，新增布局组件配置项样式，以配置项样式优先级为高
     * @param component 布局组件配置项
     * @param keyIndex 组件下标索引
     * @returns {{width: *, height: *}}
     */
    setComponentStyle(component, keyIndex) {
      //   let component = dataList.find(item => (item.rowNum == '*' || item.rowNum == rowIndex) && item.colNum == colIndex);
      // let component = this.uiContents[rowIndex + '-' + colIndex];
      let renderStyle = this.renderStyle[keyIndex];
      if (component) {
        let style = {};
        if (component.width) {
          if(typeof component.width === 'number' || !isNaN(component.width)){
            style.width = component.width + "px";
          }else{
            style.width = component.width;
          }
        }
        if (component.height) {
          if(typeof component.height === 'number' || !isNaN(component.height)){
            style.height = component.height + "px";
          }else{
            style.height = component.height;
          }
        }
        if (component.minWidth) {
          if(typeof component.minWidth === 'number' || !isNaN(component.minWidth)){
            style.minWidth = component.minWidth + 'px';
          }else{
            style.minWidth = component.minWidth;
          }
        }
        if (component.minHeight) {
          if(typeof component.minHeight === 'number' || !isNaN(component.minHeight)){
            style.minHeight = component.minHeight + "px";
          }else{
            style.minHeight = component.minHeight;
          }
        }
        //覆盖原有样式
        if(renderStyle){
          this.renderStyle[keyIndex] = {...renderStyle, ...style};
        }else{
          this.renderStyle[keyIndex] = {...style};
        }
      }
    },
    /**
     * 设置指定布局组件div宽度为0
     * @param commp 需要调整的组件实例
     * @param direction 需要缩放的方向 ，e、s、w、n ，分为东南西北
     */
    setSpecifyCommpWidthToZero(commp, direction) {
      //获取布局组件容器div
      let layoutDiv = commp.$el.parentNode;
      //生成jquery对象
      let layoutJq = jQuery(layoutDiv);
      //找layoutJq的第一个兄弟节点
      let sibling;
      //方向为 e 和 s的延展
      if (!direction || direction == 'e' || direction == 's') {
        //获取组件相邻的下一个兄弟节点
        if (direction == 'e') {
          sibling = layoutJq.next();
          this.setCommpWidthToZero(layoutJq, sibling);
        } else {
          layoutJq = layoutJq.parent();
          sibling = layoutJq.next();
          this.setCommpHeightToZero(layoutJq, sibling);
        }
      }
      //方向为 w 和 n的延展
      else {
        //获取组件相邻的上一个兄弟组件
        if (direction == 'w') {
          sibling = layoutJq.prev();
          this.setCommpWidthToZero(layoutJq, sibling);
        } else {
          layoutJq = layoutJq.parent();
          sibling = layoutJq.prev();
          this.setCommpHeightToZero(layoutJq, sibling);
        }
      }
    },
    /**
     * 设置组件的宽度为0，如果组件有设置最小宽度，则按照最小宽度来设置组件的宽度
     * @param {*} layoutJq 需要设置的组件
     * @param {*} sibling 组件下一个
     */
    setCommpWidthToZero(layoutJq, sibling) {
      //最小宽度
      let minWidth = layoutJq.attr("min-width");
      minWidth = minWidth ? minWidth : 0;
      //获取当前布局组件div的宽度
      let outerWidth = layoutJq.outerWidth();
      //设置layoutJq的宽度为0
      layoutJq.width(minWidth);
      //设置兄弟节点的宽度为原来基础上加上outerWidth
      sibling.width(sibling.width() + outerWidth - minWidth);
    },
    /**
     * 设置组件高度为0，如果组件有设置最小高度，则按照最小高度来调整
     * @param {*} layoutJq 需要设置的组件
     * @param {*} sibling 组件下一个组件，需要被调整宽度的组件
     */
    setCommpHeightToZero(layoutJq, sibling) {
      //最小宽度
      let minHeight = layoutJq.attr("min-height");
      minHeight = minHeight ? minHeight : 0;
      //组件高度
      let outerHeight = layoutJq.outerHeight();
      //设置layoutJq的宽度为0
      layoutJq.height(minHeight);
      //设置兄弟节点的宽度为原来基础上加上outerWidth
      sibling.height(sibling.height() + outerHeight - minHeight);
    },

    /**
     * 还原指定div的宽度为指定宽度
     * @param commp 需要调整的组件
     * @param width 需要展开的宽度
     * @param direction 需要展开的方向，e、s、w、n ，分为东南西北
     */
    reductionSpecifyCommpWidth(commp, width, direction) {
      let layoutDiv = commp.$el.parentNode;
      //生成jquery对象
      let layoutJq = jQuery(layoutDiv);
      //找layoutJq的第一个兄弟节点
      let sibling;
      if (!direction || direction == 'e' || direction == 's') {
        //获取组件相邻的下一个兄弟节点
        if (direction == 'e') {
          sibling = layoutJq.next();
          this.reductionCommpWidth(layoutJq, sibling, width);
        } else {
          layoutJq = layoutJq.parent();
          sibling = layoutJq.next();
          this.reductionCommpHeight(layoutJq, sibling, width);
        }
      }
      //方向为 w 和 n的延展
      else {
        //获取组件相邻的上一个兄弟组件
        if (direction == 'w') {
          sibling = layoutJq.prev();
          this.reductionCommpWidth(layoutJq, sibling, width);
        } else {
          layoutJq = layoutJq.parent();
          sibling = layoutJq.prev();
          this.reductionCommpHeight(layoutJq, sibling, width);
        }
      }
    },
    /**
     * 设置指定组件的宽度
     * @param {需要被设置的组件} layoutJq
     * @param {需要调整的组件相邻的组件} sibling
     * @param {需要调整的宽度} width
     */
    reductionCommpWidth(layoutJq, sibling, width) {
      //最小宽度
      let minWidth = layoutJq.attr("min-width");
      //比较最小值
      if (width < minWidth) {
        width = minWidth;
      }
      //设置组件的宽度
      layoutJq.width(width);
      //设置兄弟节点的宽度为原来基础上减去width的宽度
      sibling.width(sibling.outerWidth() - width);
    },
    /**
     * 设置指定组件的高度
     * @param {需要调整高度的组件} layoutJq
     * @param {需要调整高度组件的相邻组件} sibling
     * @param {需要调整的高度} height
     */
    reductionCommpHeight(layoutJq, sibling, height) {
      //最小宽度
      let minHeight = layoutJq.attr("min-height");
      //比较最小值
      if (height < minHeight) {
        height = minHeight;
      }
      //设置组件的高度
      layoutJq.height(height);
      //设置兄弟节点的高度为原来基础上减去height的宽度
      sibling.height(sibling.outerHeight() - height);
    },
    /**
     *
     * @param renderStyles 渲染样式配置生成
     */
    createLayoutStyle(renderStyles){
        for(let i=0;i<renderStyles.length;i++){
            let item = renderStyles[i];
            //替换字符串中的换行符，单引号
            try{
                let styleStr = item.style.replace(/\n/g,'').replace(/'/g,'"');
                let styleObj = JSON.parse(styleStr);
                this.$set(this.renderStyle, item.rowNum + "-" + item.colNum, styleObj);
            }catch(err){
                console.log(err);
            }
        }
    },
    /**
     * 查询策略UI布局界面
     */
    queryStrategyUi(dataList) {
      for (let i = 0; i < dataList.length; i++) {
        let item = dataList[i];
        let keyIndex = item.rowNum + '-' + item.colNum;
        //赋值默认值
        if (!this.defaultData[keyIndex]) {
          this.$set(this.defaultData, keyIndex, {
            defaultData: {}, //页面数据内容
            resourceId: '', //资源ID
            resourceTypeId: '',//资源类型ID
            formId: '',//资源表单ID
            partIndex: '',//资源部件索引
            queryParam: {}//其他查询参数
          });
        }
        if (item && item.component) {
          if (item.component.startsWith('design')) {
            let op = item.component.replaceAll('design_', "");
            ajax.post("/uavMesh/operation/getOperationUiContentByProcessKey", {processKey: op}).then(res => {
              if (res.data.data.design) {
                let content = res.data.data.design.uiContent;
                content.pageName = op;
                content.component = item.component;
                // content.width = item.width;
                // content.minWidth = item.minWidth;
                // content.height = item.height;
                // content.minHeight = item.minHeight;
                this.setComponentStyle(item, keyIndex);
                this.$set(this.uiContents, keyIndex, content);
              }
            })
          } else {
            this.setComponentStyle(item, keyIndex);
            this.$set(this.uiContents, keyIndex, item);
          }
        }
      }
    },
  }
}
</script>

<style scoped lang="less">
.layoutContainer {
  width: 100%;
  height: 100%;

  .resizableRow {
    width: auto;
    height: 100%;
    //   overflow-y: auto;
    .resizableCol {
      width: auto;
      height: 100%;
      display: inline-block;
      //   overflow-x: auto;
    }
  }
}
</style>
